use std::time::Duration;

use tokio::{
    process::{Child, Command},
    time,
};

use crate::{Configure, Error, Result};

/// carla进程控制.
///
/// 启动一个carla进程,使用指定的rpc端口.
pub struct CarlaProcess {
    child: Child,
}

impl CarlaProcess {
    pub async fn new(config: &Configure) -> Result<Self> {
        let exe_name = if cfg!(target_os = "windows") {
            "CarlaUE4.exe"
        } else {
            "CarlaUE4.sh"
        };
        let exe_path = config.carla_path.clone().join(exe_name);

        let child = Command::new(exe_path)
            .arg(format!("--carla-rpc-port={}", config.carla_addr.port()))
            .arg("-quality-level=Epic")
            .spawn()
            .map_err(Error::from)?;

        // TODO: 等待一段时间,让carla进程完全加载
        time::sleep(Duration::from_secs(6)).await;

        Ok(Self { child })
    }
}

/// 析构时终止进程.
impl Drop for CarlaProcess {
    fn drop(&mut self) {
        if cfg!(target_os = "windows") {
            Command::new("taskkill")
                .args(&[
                    "/pid",
                    self.child.id().unwrap().to_string().as_str(),
                    "/f",
                    "/t",
                ])
                .spawn()
                .ok();
        } else {
            self.child.start_kill().ok();
        }
    }
}
